/*
 * @lc app=leetcode.cn id=79 lang=java
 *
 * [79] 单词搜索
 *
 * https://leetcode.cn/problems/word-search/description/
 *
 * algorithms
 * Medium (46.34%)
 * Likes:    1569
 * Dislikes: 0
 * Total Accepted:    417.7K
 * Total Submissions: 901.8K
 * Testcase Example:  '[["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]]\n"ABCCED"'
 *
 * 给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中，返回 true ；否则，返回 false
 * 。
 * 
 * 单词必须按照字母顺序，通过相邻的单元格内的字母构成，其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。
 * 
 * 
 * 
 * 示例 1：
 * 
 * 
 * 输入：board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word =
 * "ABCCED"
 * 输出：true
 * 
 * 
 * 示例 2：
 * 
 * 
 * 输入：board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word =
 * "SEE"
 * 输出：true
 * 
 * 
 * 示例 3：
 * 
 * 
 * 输入：board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word =
 * "ABCB"
 * 输出：false
 * 
 * 
 * 
 * 
 * 提示：
 * 
 * 
 * m == board.length
 * n = board[i].length
 * 1 
 * 1 
 * board 和 word 仅由大小写英文字母组成
 * 
 * 
 * 
 * 
 * 进阶：你可以使用搜索剪枝的技术来优化解决方案，使其在 board 更大的情况下可以更快解决问题？
 * 
 */

// @lc code=start
class Solution {
    boolean flag[][];
    public boolean exist(char[][] board, String word) {
        char[] chars=word.toCharArray();
        for (int i = 0; i < board.length; i++) {
            for (int j = 0; j < board[0].length; j++) {
                flag=new boolean[board.length][board[0].length];
                if (bfs(board, chars, i, j, 0)) {
                    return true;
                }
            }
        }
        
        return false;
    }

    private boolean bfs(char[][] board, char[] chars, int i, int j,int count) {
        if (i<0||j<0||i>board.length-1||j>board[0].length-1||flag[i][j]) {
            return false;
        }
        if (chars[count]==board[i][j]) {
            flag[i][j]=true;
            count++;
            // System.out.println(""+i+" "+j+" "+count);
            if (count>=chars.length) {
                return true;
            }
        }else{
            return false;
        }
        
        boolean res= bfs(board, chars, i-1, j, count)||bfs(board, chars, i+1, j, count)||bfs(board, chars, i, j-1, count)||bfs(board, chars, i, j+1, count);
        flag[i][j]=false;
        return res;
    }
}
// @lc code=end

